package com.taiji.dicom4platform.common.security.config;

import com.taiji.dicom4platform.common.security.filter.AuthenticationFilter;
import com.taiji.dicom4platform.common.security.handler.AuthenticationEntryPointImpl;
import com.taiji.dicom4platform.common.security.handler.FieldFillHandler;
import com.taiji.dicom4platform.common.security.handler.LogoutSuccessHandlerImpl;
import com.taiji.dicom4platform.common.security.provider.SecurityAuthenticationProvider;
import com.taiji.dicom4platform.common.security.service.TokenService;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


/**
 * 安全配置
 *
 * @Description
 * @Author fanxl
 * @Date 2021/5/19
 **/
@Configuration
@AllArgsConstructor
@AutoConfigureAfter(OauthAutoConfig.class)
@Import({AuthenticationFilter.class, LogoutSuccessHandlerImpl.class
        , AuthenticationEntryPointImpl.class, TokenService.class, FieldFillHandler.class})
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private AuthenticationFilter authenticationFilter;
    /**
     * 退出处理类
     */
    private LogoutSuccessHandlerImpl logoutSuccessHandler;

    private AuthenticationEntryPointImpl authenticationEntryPoint;

    private SecurityAuthenticationProvider securityAuthenticationProvider;


    /**
     * 解决 无法直接注入 AuthenticationManager
     *
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        //以下五步是表单登录进行身份认证最简单的登陆环境
        httpSecurity.csrf().disable()
                .authorizeRequests()
                .antMatchers("/login/*", "/oauth/*", "/druid/**", "/static/**",
                        "/v2/api-docs", "/swagger-resources/**", "/swagger-ui.html", "/webjars/**",
                        "/actuator/*", "/actuator","/api/mgr/loadActors","/api/user/login"
                ).permitAll()
                .anyRequest().authenticated().and()
                // 认证失败处理类
                .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint).and()
                //退出登录自己来控制
                .logout().disable().cors().and()
                //因为没用到cookies,所以关闭cookies
                //验证token
                .authenticationProvider(securityAuthenticationProvider)
                .addFilterBefore(authenticationFilter, UsernamePasswordAuthenticationFilter.class)
                .logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
    }
}
